(function () {
	/**
	 * 数据对象提交类
	 * {
	 *		area: 'templateArea', 
	 *		mdl: 'templateName', 
	 *		op: '',  -- what is this?
	 *		data: [{
	 * 			key1: value2,
	 * 			key2: value2,
	 * 			...
	 * 			SUBNODE: [{
	 * 				// such as root
	 * 			}, ...]
	 * 		}]
	 * }
	 */
	class Boundex {
		static get OPWITHKEY() {
			return 0
		}
		
		static get DELWITHKEY() {
			return 1
		}
		
		static get UPDATEWITHKEY() {
			return 2
		}
		
		static get INSERTANYWAY() {
			return 10
		}
		
		static get DONOTHING() {
			return 100
		}
		
		/**
		 * 构造函数
		 * @param templateArea {string} 
		 * @param templateName {string}
		 * @param operation {integer} 操作类型，包括 0,1,2,10,100五种类型。
		 * 	0: 根据主键操作新增或删除
		 * 	1: 根据主键删除记录
		 *	2: 根据主键更新记录
		 *	10: 不查重直接新增
		 *	100: 不操作记录 
		 */
		constructor(templateArea, templateName, operation) {
			this.area = templateArea || ''
			this.key = templateName || ''
			this.op = operation || 0
			this.data = []
			this.add()
			
			if (! this.key)
				this.op = 100;
		}
		
		/**
		 * 创建新数据行时调用，返回行对象。初始创建Bound对象时，默认已经创建了一行
		 * @return bean {object} 行数据对象
		 */
		add () {
			let bean = {
				SUBNODE: []
			}
			this.data.push(bean)
			return bean;
		}
		
		/**
		 * 对当前行数据对象进行赋值操作，默认当前数据行即为最末行
		 * @return bean {object} 行数据对象
		 */
		put (key, value) {
			let bean = this.data[this.data.length - 1]
			bean[key] = value
			return bean
		}
		
		/**
		 * 在当前行数据对象中加入一个子Bound对象
		 * @return bean {object} 行数据对象
		 */
		addSub (sub) {
			let bean = this.data[this.data.length - 1]
			bean.SUBNODE.push(sub)
			return bean;
		}
		
		/**
		 * 创建一个新的Bound对象，并加入到当前行数据对象中
		 * @return Bound {object}
		 */
		createSub (templateArea, templateName, operation) {
			let bound = new Bound(templateArea, templateName, operation)
			this.addSub(bound)
			return bound;
		}

		/**
		 * 返回当前Bound对象的数据JSON报文
		 */
		getData() {
			let bean = {
				area: this.area,
				mdl: this.key,
				op: this.op,
				data: []
			}
			this.data.forEach(function(v) {
				let record = {
					SUBNODE: []
				}
				for(let key in v) {
					if (key == 'SUBNODE') {
						v[key].forEach(function(sub) {
							record.SUBNODE.push(sub.getData())
						})
					} else {
						record[key] = v[key]
					}
				}
				bean.data.push(record)
			})
			return bean
		}
	}
	
	window.Boundex = Boundex;
})()
